#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include "Mutex.hpp"

using namespace MyMutex;

int ticket = 1000;

struct Data
{
    Data(const std::string &name, Mutex *plock)
        : _name(name),
          _plock(plock)
    {
    }

    std::string _name;
    Mutex *_plock;
};

void *route(void *arg)
{
    Data *d = static_cast<Data *>(arg);
    while (1)
    {
        {
            LockGuard lock_guard(d->_plock);
            if (ticket > 0)
            {
                usleep(1000);
                printf("%s sells ticket:%d\n", d->_name.c_str(), ticket);
                ticket--;
            }
            else
            {
                break;
            }
        }
        usleep(10);
    }
    return nullptr;
}

int main()
{
    Mutex lock; // 用自己实现的锁

    Data d1("thread 1", &lock);
    Data d2("thread 2", &lock);
    Data d3("thread 3", &lock);
    Data d4("thread 4", &lock);

    pthread_t t1, t2, t3, t4;
    pthread_create(&t1, NULL, route, &d1);
    pthread_create(&t2, NULL, route, &d2);
    pthread_create(&t3, NULL, route, &d3);
    pthread_create(&t4, NULL, route, &d4);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);
    pthread_join(t4, NULL);

    return 0;
}

//////////////////////////////////用自己封装的mutex/////////////////////////////////
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <string>
// #include <iostream>
// #include "Mutex.hpp"

// using namespace MyMutex;

// int ticket = 100;
// struct Data
// {
//     Data(const std::string &name, Mutex *plock)
//         : _name(name),
//           _plock(plock)
//     {
//     }

//     std::string _name;
//     Mutex *_plock;
// };

// void *route(void *arg)
// {
//     Data *d = static_cast<Data *>(arg);
//     while (1)
//     {
//         d->_plock->Lock(); // 加锁
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("%s sells ticket:%d\n", d->_name.c_str(), ticket);
//             ticket--;
//             d->_plock->UnLock(); // 解锁
//         }
//         else
//         {
//             d->_plock->UnLock(); // 解锁
//             break;
//         }
//     }
//     return nullptr;
// }

// int main()
// {
//     Mutex lock; //用自己实现的锁
//     Data d1("thread 1", &lock);
//     Data d2("thread 2", &lock);
//     Data d3("thread 3", &lock);
//     Data d4("thread 4", &lock);

//     pthread_t t1, t2, t3, t4;
//     pthread_create(&t1, NULL, route, &d1);
//     pthread_create(&t2, NULL, route, &d2);
//     pthread_create(&t3, NULL, route, &d3);
//     pthread_create(&t4, NULL, route, &d4);

//     pthread_join(t1, NULL);
//     pthread_join(t2, NULL);
//     pthread_join(t3, NULL);
//     pthread_join(t4, NULL);

//     return 0;
// }

///////////////////////////////////////锁接口的使用/////////////////////////////////////////
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <unistd.h>
// #include <pthread.h>
// #include <string>
// #include <iostream>
// #include <mutex>
// std::mutex cpp_mutex;
// int ticket = 100;
// struct Data
// {
//     Data(const std::string &name, pthread_mutex_t *plock)
//         : _name(name),
//           _plock(plock)
//     {}

//     std::string _name;
//     pthread_mutex_t *_plock;
// };

// void *route(void *arg)
// {
//     Data* d = static_cast<Data *>(arg);
//     while (1)
//     {
//         //pthread_mutex_lock(d->_plock); // 加锁
//         cpp_mutex.lock(); //加锁
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("%s sells ticket:%d\n", d->_name.c_str(), ticket);
//             ticket--;
//             //pthread_mutex_unlock(d->_plock); // 解锁
//             cpp_mutex.unlock(); //解锁
//         }
//         else
//         {
//             //pthread_mutex_unlock(d->_plock); // 防止走到else时锁没解
//             cpp_mutex.unlock(); //解锁
//             break;
//         }
//     }
//     return nullptr;
// }

// int main()
// {
//     pthread_mutex_t lock;  // 局部锁
//     pthread_mutex_init(&lock, nullptr); // 对锁初始化

//     Data d1("thread 1", &lock);
//     Data d2("thread 2", &lock);
//     Data d3("thread 3", &lock);
//     Data d4("thread 4", &lock);

//     pthread_t t1, t2, t3, t4;
//     pthread_create(&t1, NULL, route, &d1);
//     pthread_create(&t2, NULL, route, &d2);
//     pthread_create(&t3, NULL, route, &d3);
//     pthread_create(&t4, NULL, route, &d4);

//     pthread_join(t1, NULL);
//     pthread_join(t2, NULL);
//     pthread_join(t3, NULL);
//     pthread_join(t4, NULL);

//     pthread_mutex_destroy(&lock); // 销毁锁

//     return 0;
// }